from flask import Flask, request, Response,jsonify
import subprocess
import os
import json
import threading
import queue
import chardet
import json
import uuid


from api_gen_v2 import gen_video_impl,get_video_length

app = Flask(__name__)



def execute_process(commands, event_stream):
    try:
        process = subprocess.Popen(commands, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=False)

        def decode_stream(stream):
            while True:
                line = stream.readline()
                if not line:
                    break
                encoding = chardet.detect(line)["encoding"]
                yield line.decode(encoding).encode("utf-8")
        for line in decode_stream(process.stdout):
            event_stream.put(
                "data: " + json.dumps({"output": line.decode("utf-8")}) + "\n\n"
            )
        event_stream.put(
            "data: " + json.dumps({"exit_status": process.returncode}) + "\n\n"
        )
        event_stream.put(None)
    except Exception as e:
        event_stream.put("data: " + json.dumps({"error": str(e)}) + "\n\n")
        event_stream.put(None)


@app.route("/run")
def run():
    py_file_path = request.args.get("py")
    if not py_file_path:
        return "No 'py' parameter provided", 400
    params = request.args.get("params")
    if not params:
        return "No 'params' parameter provided", 400

    paramArray = params.split(" ")

    full_path = os.path.join("./", py_file_path)

    def generate():
        pArgs = ["python", full_path] + paramArray
        event_stream = queue.Queue()
        threading.Thread(target=execute_process, args=(pArgs, event_stream)).start()
        while True:
            event = event_stream.get()
            if event is None:
                break
            print(event)
            yield event

    return Response(generate(), content_type="text/event-stream")

@app.route('/test_print', methods=['POST'])
def test_print():
    post_data = request.get_data()  # 获取原始请求体数据
    post_data_str = post_data.decode('utf-8')  # 将请求体数据解码为字符串
    print("POST request body:", post_data_str)  # 打印请求体内容
    return 'ok'

@app.route('/save_config', methods=['POST'])
def save_config():
    config_str = request.form.get('config')

    if not config_str:
        return jsonify({"error": "config 参数不存在"}), 400

    try:
        config = json.loads(config_str)
    except json.JSONDecodeError:
        return jsonify({"error": "config 参数不是有效的 JSON 字符串"}), 400

    file_name = str(uuid.uuid4()) 

    with open(file_name, "w") as file:
        json.dump(config, file)

    return file_name

@app.route('/gen', methods=['POST'])
def gen_video():
    config_file_name = request.form.get('config')
    callback_url = request.form.get('callbackUrl')
    progress_url = request.form.get('progressUrl')

    if not config_file_name:
        return jsonify({"error": "Config file name not provided"}), 400
    if not callback_url:
        return jsonify({"error": "Callback URL not provided"}), 400
    
    try:
        with open(config_file_name, 'r') as config_file:
            config_data = json.load(config_file)
            config_file.close()
            # 删除，调试的时候可以注释掉
            os.remove(config_file_name)
    except FileNotFoundError:
        return jsonify({"error": f"Config file {config_file_name} not found"}), 404
    except json.JSONDecodeError:
        return jsonify({"error": f"Config file {config_file_name} is not a valid JSON file"}), 400
    
  
    # 生成视频 
    print(f"生成视频-配置内容: {config_data}")
    gen_video_impl(config_file_name,config_data,callback_url,progress_url)


    return jsonify(config_data)



@app.route('/get_video_length', methods=['POST'])
def w_get_video_length():
    config_file_path = request.form.get('path')
    config_file_path=config_file_path.replace("\\", "/")
    return get_video_length(config_file_path)


if __name__ == "__main__":
    app.run(debug=True)
